/*
 * @Author: liu wang wang
 * @Date: 2020-07-10 13:27:13
 * @LastEditTime: 2020-08-31 10:33:32
 * @LastEditors: liu wang wang
 * @Description: Api基础请求类
 * @FilePath: \st-sdk-js\src\api\base.ts
 */
import { apiConfig } from '../config/index';
import { RequestConfig, KaisaAjaxResponse } from '../../types';
import { bulidURL } from '../utils/url';
import { transformRequest, transformResponse } from '../utils/data';
import { processHeaders, parseHeaders } from '../utils/headers';
import store from '../utils/store';
class Request {
    constructor() {
    }
    protected empty() {

    }
    protected error(err: Error): never {
        throw new Error(err.message);
    }
    // 发起请求
    protected xhr(config: RequestConfig): void {
        const { url, method = 'get', data, headers, responseType, success = this.empty, error = this.error } = config;
        const request: XMLHttpRequest | null = new XMLHttpRequest();
        const that = this;
        if (responseType) {
            request.responseType = responseType
        }
        request.open(method.toUpperCase(), url, true);
        request.timeout = apiConfig.timeout;
        request.onreadystatechange = function handleLoad() {
            if (request.readyState !== 4) {
                return
            }
            const responseHeaders = parseHeaders(request.getAllResponseHeaders())
            const responseData = responseType && responseType !== 'text' ? request.response : request.responseText
            const response: KaisaAjaxResponse = {
                data: responseData,
                status: request.status,
                statusText: request.statusText,
                headers: responseHeaders,
                config,
                request
            }
            that.transformResponseData(response);
            if(response.status === 200){
                success(response.data);
            }
        }
        request.onerror=function(err){
            throw new Error(err.type+':签名接口配置有误');
        }
        Object.keys(headers).forEach((name) => {
            if (data === null && name.toLowerCase() === 'content-type') {
                delete headers[name]
            } else {
                request.setRequestHeader(name, headers[name])
            }
        })
        request.ontimeout = function(err){
            console.log(err)
        }
        request.send(data);
    }
    // 请求接口
    public ajax(config: RequestConfig): void {
        const nconfig = {
            headers:{
                sign:store.getStore('sign')
            },
            ...config
        }
        this.processConfig(nconfig)
        this.xhr(nconfig);
    }
    // 统一处理config参数
    protected processConfig(config: RequestConfig): void {
        const urlType = config.url.split(':')[0];
        if(urlType!=='http' && urlType!=='https'){
            config.url = apiConfig.baseUrl + this.transformUrl(config)
        }else{
            config.url = config.url.replace('http://','//');
        }
        config.headers = this.transformHeaders(config);
        config.data = this.transformRequestData(config);
    }
    // 处理URL参数
    protected transformUrl(config: RequestConfig): string {
        const { url, params } = config
        return bulidURL(url, params)
    }
    // 处理post数据
    protected transformRequestData(config: RequestConfig): any {
        return transformRequest(config.data);
    }
    // 处理headers
    protected transformHeaders(config: RequestConfig): any {
        let { headers = {}, data } = config;
        return processHeaders(headers, data);
    }
    // 处理响应数据
    protected transformResponseData(res: KaisaAjaxResponse): any {
        res.data = transformResponse(res.data);
    }
}

export default Request;